package model.core.torneo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import model.core.document.AbstractDocumentable;
import model.core.utente.Commissario;
import model.core.utente.Giocatore;
import model.core.utente.GiocatoreInterface;
import model.core.utente.Squadra;
import model.utility.Utility;

/**
 * 
 * @author Giuseppe Fusco (fusgius19@gmail.com)
 *
 */
public class Torneo extends AbstractDocumentable implements StatoTorneo  {

	private String nome;

	private String tipologia;

	private int numero_edizione;

	private int anno_svolgimento;

	private Classifica classifica;

	private List<Gara> calendario;

	private Commissione commissione;

	private boolean isSingolo;

	private String stato;

	private GiocatoreInterface vincitore;

	/**
	 * 
	 * @param maxComponenti
	 * @param minComponenti
	 * @throws IllegalArgumentException
	 */
	public Torneo(int maxComponenti, int minComponenti){
		creaClassifica(maxComponenti, minComponenti);
		numero_edizione = 1;
		anno_svolgimento = new GregorianCalendar().get(Calendar.YEAR);
		stato = SCHEDULATO;
		calendario = new ArrayList<Gara>();
		this.commissione = new Commissione();
		isSingolo=true;
	}

	public Torneo(){
		isSingolo=true;
		creaClassifica(2, 2);
		numero_edizione = 1;
		anno_svolgimento = new GregorianCalendar().get(Calendar.YEAR);
		stato = SCHEDULATO;
		calendario = new ArrayList<Gara>();
		this.commissione = new Commissione();
	}

	public int getMaxComponenti() {
		return  classifica.getMaxComponenti();
	}

	public int getMinComponenti() {
		return classifica.getMinComponenti();
	}

	public void setMaxComponenti(int maxComponenti) {
		classifica.setMaxComponenti(maxComponenti);
	}

	public void setMinComponenti(int minComponenti) {
		classifica.setMinComponenti(minComponenti);
	}

	private void creaClassifica(int maxComponenti, int minComponenti) {
		this.classifica = new Classifica(maxComponenti, minComponenti);
	}

	public GiocatoreInterface getVincitore() {
		return vincitore;
	}

	/**
	 * 
	 * @param vincitore
	 * @throws IllegalArgumentException
	 */
	public boolean setVincitore(GiocatoreInterface vincitore)throws IllegalArgumentException {
		if(Utility.isThereGiocatore(this.classifica.getGiocatori(), vincitore))
		{
			this.vincitore = vincitore;
			return true;
		}
		else
			return false;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getTipologia() {
		return tipologia;
	}

	public void setTipologia(String tipologia) {
		this.tipologia = tipologia;
	}

	public int getNumero_edizione() {
		return numero_edizione;
	}

	public void setNumero_edizione(int numero_edizione) {
		if(numero_edizione>=1)
			this.numero_edizione = numero_edizione;
	}

	public int getAnno_svolgimento() {
		return anno_svolgimento;
	}

	public void setAnno_svolgimento(int anno_svolgimento) {
		this.anno_svolgimento = anno_svolgimento;
	}

	public Classifica getClassifica() {
		return classifica;
	}

	public void setClassifica(Classifica classifica) {
		this.classifica = classifica;
	}

	public List<Gara> getCalendario() {
		return calendario;
	}
	
	public boolean addGara(Gara gara) {
		return calendario.add(gara);
	}

	public boolean removeGara(Gara gara) {
		return calendario.remove(gara);
	}

	public void setCalendario(List<Gara> calendario) {
		this.calendario = calendario;
	}

	public Commissione getCommissione() {
		return commissione;
	}

	public void setCommissione(Commissione commissione) {
		this.commissione = commissione;
	}

	public boolean isSingolo() {
		return isSingolo;
	}

	public void setSingolo(boolean isSingolo) {
		this.isSingolo = isSingolo;
		if(this.isSingolo)
			this.classifica.setGiocatori(new ArrayList<Giocatore>());
		else
			this.classifica.setGiocatori(new ArrayList<Squadra>());
	}

	public String getStato() {
		return stato;
	}

	/**
	 * 
	 * @param stato
	 * @throws IllegalStateException
	 */
	public boolean setStato(String stato)throws IllegalStateException{
		if(stato.equals(SCHEDULATO))
			return false;
		else{
			switch (this.stato) {
			case ANNULLATO:
				return true;
			case TERMINATO:
				return true;
			default:
				this.stato=stato;
				return true;
			}	
		}
	}

	public boolean addCommissario(Commissario c){
		boolean v = true;
		for(GiocatoreInterface g: classifica.getGiocatori()){
			if(g instanceof Giocatore){
				Giocatore gi = (Giocatore) g;
				if(gi.getMatricola().equals(c.getMatricola()))
				{
					v = false;
					break;
				}
			}else if(g instanceof Squadra){
				Squadra s = (Squadra) g;
				for(Giocatore gg: s.getPartecipanti())
					if(gg.getMatricola().equals(c.getMatricola()))
					{
						v = false;
						break;
					}	
			}else{
				v = false;
				break;
			}
		}
		if(v)
			v = this.commissione.addCommissario(c);
		return v;
	}

	public boolean removeCommissario(Commissario c){
		return this.commissione.removeCommissario(c);
	}

	public boolean addGiocatore(GiocatoreInterface g){
		return this.classifica.addGiocatore(g, this.isSingolo);
	}

	public boolean removeGiocatore(GiocatoreInterface g){
		return this.classifica.removeGiocatore(g);
	}

	public boolean isGiocatoreDelTorneo(GiocatoreInterface g){
		if(isSingolo && (g instanceof Giocatore))
		{
			return Utility.isThereGiocatore(getClassifica().getGiocatori(), g);
		}
		else if(!isSingolo && (g instanceof Giocatore)){
			for(GiocatoreInterface s: getClassifica().getGiocatori()){
				if(Utility.isThereGiocatore(((Squadra)s).getPartecipanti(), g))
					return true;
			}
			return false;
		}else
			return false;
	}
}
